package healththink

class Facility {
    String name
    double latitude
    double longitude
    FacilityType facilityType
    Address primaryAddress
    FacilitySite facilitySite
    Boolean isInOperation = true

    static hasMany = [facilitySvcs: FacilitySvc,
            facilityAttributes: FacilityAttributeLink,
            facilityScheduleEntries: FacilityScheduleEntry,
            addresses: Address,
            phones: TelephoneNumber,
            forums: Forum,
            facilityUsers: FacilityUserLink,
            facilityGroups: FacilityGroupLink]

    static constraints = {
            name(size:1..128, blank: false, unique:true)
            latitude(blank: false)
            longitude(blank: false)
            facilityType(blank: false)
            facilitySite(blank:true, nullable:true)
            primaryAddress(blank: true, nullable:true)
            isInOperation(blank:false)
    }
	
    static fetchMode = [
        forums:"eager"
    ]
    
    static mapping = {
        facilitySite lazy: false
        primaryAddress lazy: false
    }
    
    String toString(){
        name
    }
    
    double getDistance(double lat, double lon)
    {
        double R = 6371; // km, raidus of earth
        double dLat = Math.toRadians(latitude-lat);
        double dLon = Math.toRadians(longitude-lon);
        //lat1 is this.latitude
        double lat1 = Math.toRadians(latitude);
        double lat2 = Math.toRadians(lat);

        double ang = Math.sin(dLat/2) * Math.sin(dLat/2) +
                Math.sin(dLon/2) * Math.sin(dLon/2) * Math.cos(lat1) * Math.cos(lat2); 
        double crd = 2 * Math.atan2(Math.sqrt(ang), Math.sqrt(1-ang)); 
        double dis = R * crd;  
        return dis
    }
    
    static double getDistance(
        double lat,
        double lat0, 
        double lon,
        double lon0
    )
    {
        double R = 6371; // km, raidus of earth
        double dLat = Math.toRadians(lat-lat0);
        double dLon = Math.toRadians(lon-lon0);
        //lat1 is this.latitude
        double lat1 = Math.toRadians(lat);
        double lat2 = Math.toRadians(lat0);

        double ang = Math.sin(dLat/2) * Math.sin(dLat/2) +
                Math.sin(dLon/2) * Math.sin(dLon/2) * Math.cos(lat1) * Math.cos(lat2); 
        double crd = 2 * Math.atan2(Math.sqrt(ang), Math.sqrt(1-ang)); 
        double dis = R * crd;  
        return dis
    }
    
    List facilityAttributes()
    {
        return facilityAttributes.collect{it.attribute}
    }
    
    List addToFacilityAttributes(Attribute fa)
    {
        FacilityAttributeLink.link(fa, this)
        return facilityAttributes()
    }
    
    List removeFromFacilityAttributes(Attribute fa)
    {
        FacilityAttributeLink.unlink(fa, this)
        return facilityAttributes()
    }
    
    List facilityGroups(){
        return facilityGroups.collect{it.facilityGroup}
    }
    
    List addToFacilityGroups(FacilityGroup fg){
        FacilityGroupLink.link(fg, this)
        return facilityGroups()
    }
    
    List removeFromFacilityAttributes(FacilityGroup fa){
        FacilityGroupLink.unlink(fa, this)
        return facilityAttributes()
    }
    
    List facilityUsers()
    {
        return facilityUsers.collect{it.user}
    }
    
    List addToFacilityUsers(User u)
    {
        FacilityUserLink.link(u, this)
        return facilityUsers()
    }
    
    List removeFromFacilityUsers(User u)
    {
        FacilityUserLink.unlink(u, this)
        return facilityUsers()
    }
}

enum FacilityType{
    Hospital("Hospital"),
    Emergency("Emergency"),
    Clinic("Clinic"),
    Family("Family")

    final String value

    FacilityType(String value)
    {
        this.value=value
    }
}